{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入必要的库并执行所有初始化和错误处理\n",
    "import requests\n",
    "import json\n",
    "from datetime import datetime\n",
    "\n",
    "# Elasticsearch 连接配置\n",
    "ES_HOST = \"http://host.docker.internal:9200\"\n",
    "\n",
    "# 全局状态变量\n",
    "es_connected = False\n",
    "index_created = False\n",
    "data_inserted = False\n",
    "cluster_info = {}\n",
    "index_response = {}\n",
    "sample_products = []\n",
    "\n",
    "print(\"📡 Elasticsearch 操作执行中...\")\n",
    "\n",
    "try:\n",
    "    # 1. 测试连接\n",
    "    response = requests.get(ES_HOST)\n",
    "    if response.status_code == 200:\n",
    "        cluster_info = response.json()\n",
    "        es_connected = True\n",
    "        print(\"✅ Elasticsearch 连接成功\")\n",
    "    else:\n",
    "        print(f\"❌ 连接失败: HTTP {response.status_code}\")\n",
    "        \n",
    "except Exception as e:\n",
    "    print(f\"❌ 连接异常: {str(e)}\")\n",
    "\n",
    "if es_connected:\n",
    "    try:\n",
    "        # 2. 创建 products 索引\n",
    "        index_config = {\n",
    "            \"settings\": {\n",
    "                \"number_of_shards\": 3,\n",
    "                \"number_of_replicas\": 1\n",
    "            },\n",
    "            \"mappings\": {\n",
    "                \"properties\": {\n",
    "                    \"name\": {\"type\": \"text\"},      # 文本类型，支持分词\n",
    "                    \"price\": {\"type\": \"double\"},   # 数值类型\n",
    "                    \"stock\": {\"type\": \"integer\"}   # 整数类型\n",
    "                }\n",
    "            }\n",
    "        }\n",
    "        \n",
    "        url = f\"{ES_HOST}/products\"\n",
    "        headers = {\"Content-Type\": \"application/json\"}\n",
    "        response = requests.put(url, json=index_config, headers=headers)\n",
    "        \n",
    "        if response.status_code == 200:\n",
    "            index_created = True\n",
    "            index_response = response.json()\n",
    "            print(\"✅ products 索引创建成功\")\n",
    "        else:\n",
    "            print(f\"❌ 索引创建失败: HTTP {response.status_code}\")\n",
    "            \n",
    "    except Exception as e:\n",
    "        print(f\"❌ 索引创建异常: {str(e)}\")\n",
    "\n",
    "if index_created:\n",
    "    try:\n",
    "        # 3. 插入样本数据\n",
    "        sample_products = [\n",
    "            {\"name\": \"苹果手机\", \"price\": 6999.99, \"stock\": 100},\n",
    "            {\"name\": \"华为笔记本\", \"price\": 8999.50, \"stock\": 50},\n",
    "            {\"name\": \"小米耳机\", \"price\": 299.00, \"stock\": 200},\n",
    "            {\"name\": \"联想平板\", \"price\": 2999.99, \"stock\": 75}\n",
    "        ]\n",
    "        \n",
    "        success_count = 0\n",
    "        for i, product in enumerate(sample_products, 1):\n",
    "            url = f\"{ES_HOST}/products/_doc/{i}\"\n",
    "            headers = {\"Content-Type\": \"application/json\"}\n",
    "            response = requests.put(url, json=product, headers=headers)\n",
    "            \n",
    "            if response.status_code in [200, 201]:\n",
    "                success_count += 1\n",
    "        \n",
    "        if success_count == len(sample_products):\n",
    "            data_inserted = True\n",
    "            print(\"✅ 样本数据插入成功\")\n",
    "        else:\n",
    "            print(f\"⚠️ 部分数据插入失败: {success_count}/{len(sample_products)}\")\n",
    "            \n",
    "    except Exception as e:\n",
    "        print(f\"❌ 数据插入异常: {str(e)}\")\n",
    "\n",
    "print(f\"\\n🎯 操作状态: 连接={es_connected}, 索引={index_created}, 数据={data_inserted}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 显示 Elasticsearch 集群信息\n",
    "if es_connected:\n",
    "    print(\"📋 Elasticsearch 集群信息:\")\n",
    "    print(f\"• 集群名称: {cluster_info.get('cluster_name', 'N/A')}\")\n",
    "    print(f\"• 版本信息: {cluster_info.get('version', {}).get('number', 'N/A')}\")\n",
    "    print(f\"• 状态: {cluster_info.get('tagline', 'N/A')}\")\n",
    "    print(f\"• 连接地址: {ES_HOST}\")\n",
    "else:\n",
    "    print(\"❌ 无法显示集群信息：连接失败\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 显示 PUT 请求信息和索引创建结果\n",
    "if index_created:\n",
    "    # 显示请求信息\n",
    "    index_config = {\n",
    "        \"settings\": {\n",
    "            \"number_of_shards\": 3,\n",
    "            \"number_of_replicas\": 1\n",
    "        },\n",
    "        \"mappings\": {\n",
    "            \"properties\": {\n",
    "                \"name\": {\"type\": \"text\"},      # 文本类型，支持分词\n",
    "                \"price\": {\"type\": \"double\"},   # 数值类型\n",
    "                \"stock\": {\"type\": \"integer\"}   # 整数类型\n",
    "            }\n",
    "        }\n",
    "    }\n",
    "    \n",
    "    print(f\"🚀 PUT 请求信息:\")\n",
    "    print(f\"URL: {ES_HOST}/products\")\n",
    "    print(f\"Method: PUT\")\n",
    "    print(f\"Content-Type: application/json\")\n",
    "    print(f\"\\n📄 请求体:\")\n",
    "    print(json.dumps(index_config, indent=2, ensure_ascii=False))\n",
    "    \n",
    "    print(f\"\\n✅ 索引创建响应:\")\n",
    "    print(json.dumps(index_response, indent=2, ensure_ascii=False))\n",
    "    \n",
    "else:\n",
    "    print(\"❌ 无法显示索引信息：索引创建失败\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 显示插入的样本数据\n",
    "if data_inserted:\n",
    "    print(\"📦 已插入的样本数据:\")\n",
    "    print(f\"总共插入了 {len(sample_products)} 个产品\\n\")\n",
    "    \n",
    "    for i, product in enumerate(sample_products, 1):\n",
    "        print(f\"产品 {i}:\")\n",
    "        print(f\"  • 名称: {product['name']}\")\n",
    "        print(f\"  • 价格: ¥{product['price']}\")\n",
    "        print(f\"  • 库存: {product['stock']} 件\")\n",
    "        print()\n",
    "        \n",
    "else:\n",
    "    print(\"❌ 无法显示样本数据：数据插入失败\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 执行搜索查询并显示结果\n",
    "if data_inserted:\n",
    "    try:\n",
    "        search_url = f\"{ES_HOST}/products/_search\"\n",
    "        \n",
    "        # 1. 查询所有产品\n",
    "        print(\"🔍 查询所有产品:\")\n",
    "        query_all = {\"query\": {\"match_all\": {}}}\n",
    "        response = requests.get(search_url, json=query_all)\n",
    "        \n",
    "        if response.status_code == 200:\n",
    "            results = response.json()\n",
    "            total_hits = results['hits']['total']['value']\n",
    "            print(f\"📊 找到 {total_hits} 个产品:\")\n",
    "            \n",
    "            for hit in results['hits']['hits']:\n",
    "                product = hit['_source']\n",
    "                print(f\"  • ID: {hit['_id']}, 名称: {product['name']}, 价格: ¥{product['price']}, 库存: {product['stock']}\")\n",
    "        \n",
    "        # 2. 搜索包含'手机'的产品\n",
    "        print(\"\\n🔍 搜索包含'手机'的产品:\")\n",
    "        query_search = {\"query\": {\"match\": {\"name\": \"手机\"}}}\n",
    "        response = requests.get(search_url, json=query_search)\n",
    "        \n",
    "        if response.status_code == 200:\n",
    "            results = response.json()\n",
    "            total_hits = results['hits']['total']['value']\n",
    "            print(f\"📊 找到 {total_hits} 个匹配产品:\")\n",
    "            \n",
    "            for hit in results['hits']['hits']:\n",
    "                product = hit['_source']\n",
    "                score = hit['_score']\n",
    "                print(f\"  • 评分: {score}, 名称: {product['name']}, 价格: ¥{product['price']}\")\n",
    "        \n",
    "        # 3. 价格范围查询\n",
    "        print(\"\\n🔍 查询价格在1000-5000之间的产品:\")\n",
    "        query_range = {\"query\": {\"range\": {\"price\": {\"gte\": 1000, \"lte\": 5000}}}}\n",
    "        response = requests.get(search_url, json=query_range)\n",
    "        \n",
    "        if response.status_code == 200:\n",
    "            results = response.json()\n",
    "            total_hits = results['hits']['total']['value']\n",
    "            print(f\"📊 找到 {total_hits} 个价格在范围内的产品:\")\n",
    "            \n",
    "            for hit in results['hits']['hits']:\n",
    "                product = hit['_source']\n",
    "                print(f\"  • 名称: {product['name']}, 价格: ¥{product['price']}, 库存: {product['stock']}\")\n",
    "                \n",
    "    except Exception as e:\n",
    "        print(f\"❌ 搜索异常: {str(e)}\")\n",
    "        \n",
    "else:\n",
    "    print(\"❌ 无法执行搜索：没有可搜索的数据\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 操作完成总结\n",
    "print(\"🎉 Elasticsearch 操作演示完成！\")\n",
    "print(\"\\n📊 操作总结:\")\n",
    "print(f\"• Elasticsearch 连接: {'✅ 成功' if es_connected else '❌ 失败'}\")\n",
    "print(f\"• products 索引创建: {'✅ 成功' if index_created else '❌ 失败'}\")\n",
    "print(f\"• 样本数据插入: {'✅ 成功' if data_inserted else '❌ 失败'}\")\n",
    "\n",
    "if data_inserted:\n",
    "    print(f\"• 成功插入 {len(sample_products)} 个产品\")\n",
    "    print(\"• 支持全文搜索、范围查询等多种搜索方式\")\n",
    "    print(f\"• 可通过 {ES_HOST}/products/_search 进行查询\")\n",
    "\n",
    "print(f\"\\n⏰ 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\")\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "",
   "name": ""
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
